package com.object.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

import java.net.ConnectException;

import static java.awt.Color.RED;

@Slf4j
public class PdfUtil
{

    public static void main(String[] args) throws Exception
    {
        PdfUtil pdfUtil = new PdfUtil();
        pdfUtil.addWatermarksToEachPage(System.getProperty("user.dir") + "\\file", "word.docx", System.getProperty("user.dir") + "\\img\\" + "file.png");
    }

    /**
     * word转pdf
     *
     * @param wordPath word的路径
     * @param pdfPath  pdf的路径
     */
    public static void documentToPdf(String wordPath, String pdfPath)
    {
        try
        {
            String OpenOffice_HOME = "C:\\Program Files (x86)\\OpenOffice 4\\";
            //这里是OpenOffice的安装目录, 在我的项目中,为了便于拓展接口,没有直接写成这个样子,但是这样是绝对没问题的
            // 如果从文件中读取的URL地址最后一个字符不是 '\'，则添加'\'
            if (OpenOffice_HOME.charAt(OpenOffice_HOME.length() - 1) != '\\')
            {
                OpenOffice_HOME += "\\";
            }
            // 启动OpenOffice的服务
            String command = OpenOffice_HOME
                    + "program\\soffice.exe -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\"";
            Process pro = Runtime.getRuntime().exec(command);
            // connect to an OpenOffice.org instance running on port 8100
            OpenOfficeConnection connection = new SocketOpenOfficeConnection("127.0.0.1", 8100);
            // OpenOfficeConnection connection = new SocketOpenOfficeConnection("yourIP",8100);
            connection.connect();
            // convert
            DocumentConverter converter = new OpenOfficeDocumentConverter(
                    connection);
            converter.convert(new File(wordPath), new File(pdfPath));
            // close the connection
            connection.disconnect();
            // 关闭OpenOffice服务的进程
            pro.destroy();
        }
        catch (ConnectException e)
        {
            throw new RuntimeException(e);
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }


    /**
     * 给每一页pdf添加水印
     *
     * @param pdfPath  前缀路径
     * @param fileName 文件名
     * @param sealImg  印章图片的绝对路径
     * @throws Exception
     */
    public void addWatermarksToEachPage(String pdfPath, String fileName, String sealImg) throws Exception
    {
        String pdfPath1 = pdfPath + "\\" + fileName + ".pdf";
        String pdfPath0 = pdfPath + "\\" + fileName + "";
        if (!new File(pdfPath1).exists())
        {
            documentToPdf(pdfPath0, pdfPath1);
        }
        PdfReader reader = new PdfReader(pdfPath1);
        FileOutputStream outputStream = new FileOutputStream(pdfPath + "\\" + fileName + "_PDF1.pdf");
        PdfStamper pdfReader = new PdfStamper(reader, outputStream);
        // 设置密码
        // pdfReader.setEncryption("123".getBytes(),"123".getBytes(), ALLOW_PRINTING, ENCRYPTION_AES_128);
        int numberOfPages = reader.getNumberOfPages() + 1;
        BufferedImage[] images = incise(numberOfPages - 1, sealImg);
        // 水印透明度
        PdfGState gs = new PdfGState();
        gs.setFillOpacity(0.5f);
        gs.setStrokeOpacity(0.5f);
        for (int i = 1; i < numberOfPages; i++)
        {
            //获取全部的每一页的对象
            PdfContentByte content = pdfReader.getOverContent(i);
            // 透明度
            content.setGState(gs);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(images[i - 1], "png", os);
            Image image = com.lowagie.text.Image.getInstance(os.toByteArray());
            image.setAbsolutePosition(500, 500);
            // 设置图片的显示大小
            image.scaleToFit(100, 125);
            content.addImage(image);
            if ((i + 1) == numberOfPages)
            {
                //最后一页
                //設置水印文字顏色
                content.setColorFill(RED);
                content.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 12);
                //添加 签名码
                content.showTextAligned(Element.ALIGN_LEFT, "6554512351425saeqweqw", 450, 100, 25);
            }
        }

        // 释放资源
        pdfReader.close();
        reader.close();
        outputStream.close();
    }

    /**
     * 根据pdf去切割图片
     * <p>
     * 源矩阵第一个角的坐标0+0源矩阵第二个角的坐标77+92
     * 源矩阵第一个角的坐标77+0源矩阵第二个角的坐标154+92
     * 源矩阵第一个角的坐标154+0源矩阵第二个角的坐标231+92
     * 源矩阵第一个角的坐标0+92源矩阵第二个角的坐标77+184
     * 源矩阵第一个角的坐标77+92源矩阵第二个角的坐标154+184
     * 源矩阵第一个角的坐标154+92源矩阵第二个角的坐标231+184
     * 源矩阵第一个角的坐标0+184源矩阵第二个角的坐标77+276
     * 源矩阵第一个角的坐标77+184源矩阵第二个角的坐标154+276
     * 源矩阵第一个角的坐标154+184源矩阵第二个角的坐标231+276
     *
     * @param cols
     * @throws Exception
     */
    private BufferedImage[] incise(int cols, String sealImg) throws Exception
    {
        // 读入大图
        File file = new File(sealImg);
        FileInputStream fis = new FileInputStream(file);
        BufferedImage image = ImageIO.read(fis);

        // 分割成3*3(9)个小图
        int rows = 1;
        //几页就分割成几份
        int chunks = rows * cols;

        // 计算每个小图的宽度和高度
        int chunkWidth = image.getWidth() / cols;
        int chunkHeight = image.getHeight() / rows;
        //     log.info("图片的宽度为:" + chunkWidth * rows + "图片的高度为:" + chunkHeight * cols);
        //大图中的一部分
        int count = 0;
        BufferedImage imgs[] = new BufferedImage[chunks];
        for (int x = 0; x < rows; x++)
        {
            for (int y = 0; y < cols; y++)
            {
                //设置小图的大小和类型
                imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType());

                //写入图像内容
                Graphics2D gr = imgs[count++].createGraphics();
                gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null);
                //        System.out.println("源矩阵第一个角的坐标" + chunkWidth * y + "+" + chunkHeight * x + "源矩阵第二个角的坐标" + chunkWidth * (y + 1) + "+" + chunkHeight * (x + 1));
                gr.dispose();
            }
        }
        return imgs;
    }
}
